package com.young.ums.service.impl;

import com.young.common.exception.BaseException;
import com.young.interfaces.ums.model.SsoVerifyDTO;
import com.young.ums.model.User;
import com.young.ums.model.SsoJWT;
import com.young.ums.model.SsoSession;
import com.young.ums.service.ISsoService;
import com.young.ums.service.ISsoSessionService;
import com.young.ums.service.IUmsConfigService;
import com.young.ums.service.IUserService;
import com.young.ums.util.SecureHandler;
import com.young.ums.util.UmsConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

/**
 * 单点登录服务
 * @author imrookie
 * @date 2018/10/1
 */
@Service("ssoService")
public class SsoServiceImpl implements ISsoService {

    private static final Logger logger = LoggerFactory.getLogger(SsoServiceImpl.class);

    @Resource(name="umsConfigService")
    IUmsConfigService configService;

    @Resource(name="ssoSessionService")
    ISsoSessionService ssoSessionService;

    @Resource(name="userService")
    IUserService userService;

    /**
     * 单点验证
     *
     * @param token
     * @return
     */
    @Override
    public SsoVerifyDTO verifySSO(String token) {
        //解析令牌
        SsoJWT ssoJWT = null;
        try {
            ssoJWT = SecureHandler.parseJWT(token, configService.getUsableConfigValue(UmsConstants.UmsConfigKey.SSO_RSA_KEY_PRIVATE), configService.getUsableConfigValue(UmsConstants.UmsConfigKey.SSO_HS256_KEY));
        } catch (Exception e) {
            logger.error("[单点登录服务-单点验证] 令牌解析出错,token={}", token, e);
            throw new BaseException("令牌解析失败");
        }

        //查询服务端回话信息,根据jwt的uuid
        SsoSession ssoSession = ssoSessionService.getByToken(ssoJWT.getPayload().getUuid());

        if (ssoSession == null){
            logger.error("[token验证] 根据令牌UUID[{}]在服务端查找失败,用户id为:{}", ssoJWT.getPayload().getUuid(), ssoJWT.getPayload().getUserId());
            return SsoVerifyDTO.buildFail(token, "验证失败");
        }

        if (UmsConstants.SsoSessionStatus.NO == ssoSession.getStatus()){//状态为禁用
            logger.warn("[token验证] 令牌[UUID={}]状态为禁用,用户id为:{}", ssoJWT.getPayload().getUuid(), ssoJWT.getPayload().getUserId());
            return SsoVerifyDTO.buildFail(token, "验证失败");
        }

        if (ssoSession.getExpireTime().before(new Date())){//已经过期
            logger.info("[token验证] 令牌已过期,令牌UUID={},用户id={}", ssoJWT.getPayload().getUuid(), ssoJWT.getPayload().getUserId());
            return SsoVerifyDTO.buildFail(token, "会话已过期");
        }

        User user = userService.get(ssoSession.getUserId());//查询用户信息

        if (user == null){
            logger.warn("[token验证] 根据用户id查询用户信息失败,用户id为:{}", ssoSession.getUserId());
            return SsoVerifyDTO.buildFail(token, "验证失败");
        }

        return SsoVerifyDTO.buildSuccess(token, user.convert2User());
    }
}
